約 2,643,804 件
https://w.atwiki.jp/bambooflow/pages/122.html
SystemC TLM-2.0クラス TLM-2.0のクラスから全体的な構成をみる。 SystemC TLM-2.0クラスTLM2.0のクラス構成ディレクトリ構成 TLM-1標準TLM-1 コア・インターフェース TLM-1 fifo インターフェース tlm_fifo マスタ・スレーブ・インタフェース TLM-2 コア・インタフェースブロッキング・トランスポート・インタフェース ノン・ブロッキング・トランスポート・インタフェース ダイレクト・メモリ・インタフェース デバッグ・トランスポート・インタフェース イニシエータとターゲット・ソケット ジェネリック・ペイロード Phases ユーティリティ便利なソケット ペイロード・イベント・キュー Quantumキーパー インスタンス仕様 拡張 解析ポート 解析インタフェース TLM2.0のクラス構成 ディレクトリ構成 include/tlm tlm_h tlm_req_rsp TLM-1.0 legacy tlm_trans TLM-2 interoperability classes tlm_2_interfaces TLM-2 core interfaces tlm_generic_payload TLM-2 generic payload tlm_sockets TLM-2 initiator and target sockets tlm_quantum TLM-2 global quantum tlm_analysis TLM-2 analysis interface, port, fifo tlm_utils TLM-2 utilities TLM-1標準 TLM-1 standard TLM-1とTLM-2は別物。 TLM-1 コア・インターフェース tlm_transport_if tlm_blocking_get_if tlm_blocking_put_if tlm_nonblocking_get_if tlm_nonblocking_put_if tlm_get_if tlm_put_if tlm_blocking_peek_if tlm_nonblocking_peek_if tlm_peek_if tlm_blocking_get_peek_if tlm_nonblocking_ge_peek_if tlm_get_peek_if TLM-1 fifo インターフェース tlm_fifo_debug_if tlm_fifo_put_if tlm_fifo_get_if tlm_fifo tlm_fifo マスタ・スレーブ・インタフェース tlm_blocking_master_if tlm_blocking_slave_if tlm_nonblocking_master_if tlm_nonblocking_slave_if tlm_master_if tlm_slave_if TLM-2 コア・インタフェース ブロッキング・トランスポート・インタフェース Blocking transport interface tlm_blocking_transport_if virtual void b_transport (TRANS trans, sc_core sc_time t)=0 TLM-2.0draft2で存在していた次のクラスがなくなっている。 tlm_fw_b_transport_if tlm_bw_b_transport_if ノン・ブロッキング・トランスポート・インタフェース Non-blocking transport intarface tlm_fw_nonblocking_transort_if virtual tlm_sync_enum nb_transport_fw (TRANS trans, PHASE phase, sc_core sc_time t)=0 tlm_bw_nonblocking_transport_if virtual tlm_sync_enum nb_transport_bw (TRANS trans, PHASE phase, sc_core sc_time t)=0 ダイレクト・メモリ・インタフェース Direct memory interface tlm_fw_direct_mem_if virtual bool get_direct_mem_ptr (TRANS trans, tlm_dmi dmi_data)=0 tlm_bw_direct_mem_if virtual void invalidate_direct_mem_ptr (sc_dt uint64 start_range, sc_dt uint64 end_range)=0 デバッグ・トランスポート・インタフェース Debug transport interface tlm_transport_dbg_if virtual unsigned int transport_dbg (TRANS trans)=0 イニシエータとターゲット・ソケット Initiator and target sockets tlm_initiator_socket tlm_target_socket ジェネリック・ペイロード Generic payload tlm_generic_payload Phases tlm_phase このパラメータは、ノン・ブロッキングI/F時、タイミングポイントを決定するのに使用する。 パラメータをイニシエータとターゲット間で使用する。 ユーティリティ 便利なソケット Convenience sockets simple_initiator_socket simple_initiator_socket_tagged simple_target_socket simple_target_socket_tagged passthrough_target_socket passthrough_target_socket_tagged multi_passthrough_initiator_socket multi_passthrough_target_socket tlm_bw_transport_ifを継承している。 tagged 入力I/Fメソッド呼び出しはどのソケットが到着したかを示すためにIDが付けられる。 tlmに次の基本ソケットがあるtlm_initiator_socket tlm_target_socket ペイロード・イベント・キュー Payload event queues(PEQ) Quantumキーパー Quantum keeper tlm_quantumkeeper インスタンス仕様 拡張 Instance-specific extension 解析ポート Analysis ports tlm_analysis_fifo<> tlm_analusis_port<> 解析インタフェース Analysis interface tlm_analysis_if<>
https://w.atwiki.jp/bambooflow/pages/114.html
sc_fifoチャネル 間違いがあったらゴメンサイ。 sc_fifoチャネル入力ポート:sc_fifo_in read () nb_read(変数) num_available() data_written_event() 出力ポート:sc_fifo_out write(値) nb_write(値) num_free() data_read_event() 信号の接続 ブロッキング/ノンブロッキングについて BCAで扱うには読み込み側 書き込み側 sc_fifoはプリミティブチャネルの1つ。 (プリミティブチャネルはプロセスを持たないチャネルのこと、対比して階層チャネルがある。) TLMレベルのモデルでよく使われる。 設計仕様が要求されないテストベンチ等では(扱いが簡単なので)よく使っている。 入力ポート:sc_fifo_in sc_fifo_inはsc_fifoの入力ポートとして作成するためのもの。 sc_fifo_in sc_port sc_fifo_in_if T ,0 を継承。 メソッドを呼び出すプロセスはSC_THREADもしくはSC_CTHREAD。 宣言例 SC_MODULE( MOD ) { sc_fifo_in sc_uint 32 fifo_data; SC_CTOR( MOD ) fifo_data( "fifo_data" ) { } }; read () fifoチャネルからブロッキング読み出しを行い、その値を返す。 もし、チャネルにデータが空のときは待つ(ブロッキングする/waitする)。 使用例 void thread_proc() { while(true) { tmp = fifo_data.read(); // データが空のときここでwaitする // fifo_dataにデータが来ることで動作開始 ・・・ } } read()はブロッキング読み込みのため、fifo_dataにデータが来なかったとき、このプロセスは停止したままの状態になってしまう。 もし、あなたがデータが来ない間も、停止させないでこのプロセスで別の仕事をさせたいことがあるときはnb_read()を使用するとよい。 nb_read(変数) fifoチャネルからノンブロッキング読み出しを行い、その値を返す。 もし、チャネルにデータが空でもブロッキングせず、戻り値としてfalse(読み出し失敗)を返す。 num_available()と組み合わせて使うとよい。 num_available() fifoチャネル内で利用可能なデータ数をint型で返す。 もし、fifoが空のときは0を返し、データがあるときはその数を返す。 使用例 void thread_proc() { while(true) { if (fifo_data.num_available() 0) { // データが空でないとき fifo_data.nb_read( tmp ); // 値を取得 } else { // データが空のときの処理 } } } data_written_event() 書き込みアクセスが発生したときに起こるイベントとしてsc_eventを返す。 使用例 void thread_proc() { while(true) { wait( fifo_data.data_written_event() ); // データ書き込みを待つ while (in_data.num_available() 0) { fifo_data.nb_read( tmp ); ・・・ } } } 出力ポート:sc_fifo_out sc_fifo_outはsc_fifoの出力ポートとして作成するためのもの。 sc_fifo_out sc_port sc_fifo_out_if T ,0 を継承。 メソッドを呼び出すプロセスはSC_THREADもしくはSC_CTHREAD。 宣言例 SC_MODULE( TB ) { sc_fifo_out sc_uint 32 fifo_data; SC_CTOR( TB ) fifo_data( "fifo_data" ) { } }; write(値) 引数の値をブロッキング書き込みでfifoにデータを渡す。 fifo内のデータ(領域)がいっぱいで空でないとき待機する(ブロッキングする/waitする)。 使用例 void thread_proc() { while(true) { ・・・ fifo_data.write(tmp); // fifoがいっぱいのときここでwaitする } } write()はブロッキング読み込みのため、fifo_dataがいっぱいだったとき、このプロセスは停止したままの状態になってしまう。 もし、あなたがfifo_dataがいっぱいになってしまっても、停止させないでこのプロセスで別の仕事をさせたいことがあるときはnb_read()を使用するとよい。 nb_write(値) 引数の値をノンブロッキング書き込みでfifoにデータを渡す。 fifo内のデータ(領域)がいっぱいで空でないとき、戻り値としてfalse(書き込み失敗)を返す。 num_free()と組み合わせて使うとよい。 num_free() fifo内で利用可能な開き領域の数をint型で返す。 もし、fifo内がいっぱいのときは戻り値として0を返す。 使用例 void thread_proc() { while(true) { ・・・ if (fifo_data.num_free() 0) { // データが空でないとき fifo_data.nb_write( tmp ); // 値を書き込む } else { // データがいっぱいのときの処理 } } } data_read_event() 読み出しアクセスが発生したときに発生するイベントsc_eventを返す。 使用例 void thread_proc() { while(true) { wait( fifo_data.data_read_event() ); // データ読み込みを待つ while (fifo_data.num_free() 5) { ・・・ fifo_data.nb_write( tmp ); // fifoの空が5より多いとき一気に書き込む } } } 信号の接続 sc_fifo_in とsc_fifo_out を接続するにはsc_fifo チャネルを使用する。 接続例 SC_MODULE( TOP ) { sc_fifo sc_uint 32 fifo_data; //チャネル宣言 MOD *mod; TB *tb; SC_CTOR( MOD ) fifo_data( "fifo_data", 32 ) // 第2引数でfifoの領域サイズを設定 { mod = new mod( "mod" ); mod- fifo_data( fifo_data ); // bind tb = new mod( "tb" ); tb- fifo_data( fifo_data ); // bind } }; コンストラクタの初期化リストでfifoの領域サイズを指定した。 指定しない(デフォルト)の場合、サイズは16が設定される。(無限サイズではないことに注意) ブロッキング/ノンブロッキングについて ブロッキングは、その関数内にwaitが存在することを意味する。 そのため使用者は、ブロッキングであることを承知した上で設計しなければならない。 逆にノンブロッキングは、その関数内にwaitが存在しないことを意味する。 ブロッキングの関数は、関数名の先頭に明示的に"b_"が付いたり、もしくは何も付かない。 ノンブロッキングの関数は、関数名の先頭に明示的に"nb_"が付く。 2種類のメソッドが用意されている場合には何かしら区別がつけられるように工夫されている。 もし、自分でインターフェースを設計する場合には、明示的に"b_"、"nb_"を付けるとよい。 BCAで扱うには たとえば、SC_CTHREADでクロックサイクルで動作するような(バス)モデルで扱うような場合にwait()を使用する。 そのときは、ブロッキングではなくノンブロッキングを使用したほうがよい。 (ブロッキングだとwait(event)を使用することになるので不都合があるかもしれない) 簡単なのはdo-while文を使用する方法。 読み込み側 データが来るまで待つ動作 SC_CTHREAD( cthread_proc, clk.pos() ); void cthread_proc() { while(true) { do { wait(); } while (fifo_data.num_available() 0); // fifoにデータが来るまで待つ fifo_data.nb_read( tmp ); // 値を読み込む ・・・ } } 書き込み側 データがいっぱいであるとき待つ動作 SC_CTHREAD( cthread_proc, clk.pos() ); void cthread_proc() { while(true) { ・・・ do { wait(); } while (fifo_data.num_free() 0); // fifo領域が空くまで待つ fifo_data.nb_write( tmp ); // 値を書き込む } }
https://w.atwiki.jp/bambooflow/pages/146.html
SystemCのモデリングでは、モジュール間の通信にインターフェース、ポートおよびチャネルを使用する。 これは、従来のハードウェア記述よりも抽象度をあげるためである。 インターフェースとポートとチャネルインターフェース ポート チャネル インターフェースとポートとチャネル インターフェース インターフェースはvirtual=0のメソッドのみで構成された抽象クラス(インターフェース・クラス)。 インターフェース・クラスはsc_interfaceを継承する。 インターフェースはポートとチャネルの基底クラスとなる。 ポートとチャネルが共通のインターフェースを持つことで接続が可能となる。 インターフェースは通常入力と出力の2つのインターフェースを準備する。 sc_interface ポート モジュールが外部との通信を行うための口。 sc_port<> template class IF, int N=1 class sc_port ... { public IF* operator- (); }; sc_portのテンプレートクラスは2つの引数をとる。 sc_portの<>には第一引数は、インターフェースを書く。 第二引数は、ポート数を書く。Nを1より大きくすることで多重ポートが実現可能。 するとsc_portはインターフェースを継承し、インターフェースのメソッドが使用できるようになる。ただし、シミュレーション実行前にチャネルとの接続が必要。 ポートのインターフェースメソッド呼出しは->を使用する。これは、operator- ()により実現している。 チャネル チャネルについて
https://w.atwiki.jp/systemc/
来場者数 = - ここには、SystemCを利用する人のためのメモを置きます。個々のメモへは、左のメモよりお進みください。 メモを新規作成された方は、暫定メニューを編集してそのメモへのリンクを追加してください。ただし、SystemCと関係ない話題は削除されますので、メモとして登録しないで下さい。また、各社の機密営業情報は記述しないで下さい。疑わしい記述は削除しますので、企業情報には出典をできるだけ明記してください。 @wikiへようこそ ウィキはみんなで気軽にホームページ編集できるツールです。 このページは自由に編集することができます。 メールで送られてきたパスワードを用いてログインすることで、各種変更(サイト名、トップページ、メンバー管理、サイドページ、デザイン、ページ管理、等)することができます まずはこちらをご覧ください。 @wikiの基本操作 用途別のオススメ機能紹介 @wikiの設定/管理 分からないことは? @wiki ご利用ガイド よくある質問 無料で会員登録できるSNS内の@wiki助け合いコミュニティ @wiki更新情報 @wikiへのお問合せフォーム 等をご活用ください @wiki助け合いコミュニティの掲示板スレッド一覧 #atfb_bbs_list その他お勧めサービスについて 大容量1G、PHP/CGI、MySQL、FTPが使える無料ホームページは@PAGES 無料ブログ作成は@WORDをご利用ください 2ch型の無料掲示板は@chsをご利用ください フォーラム型の無料掲示板は@bbをご利用ください お絵かき掲示板は@paintをご利用ください その他の無料掲示板は@bbsをご利用ください 無料ソーシャルプロフィールサービス @flabo(アットフラボ) おすすめ機能 気になるニュースをチェック 関連するブログ一覧を表示 その他にもいろいろな機能満載!! @wikiプラグイン @wiki便利ツール @wiki構文 @wikiプラグイン一覧 まとめサイト作成支援ツール バグ・不具合を見つけたら? 要望がある場合は? お手数ですが、メールでお問い合わせください。
https://w.atwiki.jp/bambooflow/pages/64.html
遅延モデル プログラム例 SC_MODULE( LAT ) { sc_in sc_uint 8 input; sc_out sc_uint 8 output; sc_uint 8 temp; sc_event ev_next; SC_CTOR( LAT ) { SC_METHOD( process1 ); sensitive input; SC_METHOD( process2 ); sensitive ev_next; } void process1() { temp = input.read(); ev_next.notify(30, SC_US); } void process2() { output.write( temp ); } }; 説明 8ビットの1入力、1出力の遅延モデル。 process1で入力の信号を監視して、外部からデータが入ってきたら、メンバ変数のtempに入力データを格納する。さらに、30us後に通知するイベントを行う。 process2でev_nextを監視し、process1からのイベントが通知されたら、出力にtempのデータを書き込む。
https://w.atwiki.jp/arcadegames/pages/15.html
== SYSTEM C == SYSTEM Cはセガが開発したアーケードゲーム用システム基板。同社製メガドライブのシステムと一部互換性を持つ。SYSTEM CとSYSTEM C2がある。 メガドライブとの違いは、音源制御用のZ80が搭載されていないこと、またADPCM音源が追加されていることなど。 == SYSTEM C == マザー シルク形番 パターン形番 == SYSTEM C2 仕様および主要チップ == マザー シルク形番 パターン形番 SYSTEM C2には基板を2枚接続し情報通信することができる専用コネクタが装着されているものもある。(ぷよぷよ通など) 音源 FM音源 YM3438 (OPN2C) (YAMAHA) 24ピンDIP ADPCM音源 uPD7759C (NEC) 40ピンDIP 315-5242 32ピンハイブリッドIC。画像用D/Aコンバータモジュール 315-5313 VDP (YAMAHA) 128ピンQFP 315-5296 I/O LSI (NEC) 100ピンQFP SYSTEMC2に実装されている315-5296
https://w.atwiki.jp/bambooflow/pages/162.html
SystemC SCVによるランダム生成 メモ書き。 基本的なランダム生成もっとも簡単なランダム生成 配分ランダム生成 重み付けランダム生成 重み付けランダム生成(レンジ指定) 制限付きランダム生成(scv_constraint_baseの使用) もう少し複雑なランダム生成構造体を使ったランダム生成 (応用)構造体+条件付きランダム生成 その他の使い方ランダム生成の停止 分布の指定順列型ランダム生成(RANDOM_AVOID_DUPLICATE) 参照 基本的なランダム生成 もっとも簡単なランダム生成 例:範囲0〜10の整数をランダム生成 // int型のランダム変数data_pを用意 scv_smart_ptr int data_p( "data" ); data_p- keep_only( 0, 10 ); // 0~10までをランダム生成とする設定 for (int i=0; i 10; i++) { data_p- next(); // ランダムの更新(これを実行しないといつまでも同じ値のまま) printf( "data = %d\n", data_p- read() ); // 値を取得 } 実行結果 data = 1 data = 10 data = 6 data = 8 data = 10 data = 2 data = 9 data = 3 data = 0 data = 7 配分ランダム生成 例:範囲を0〜2と99〜100の整数値をランダム生成 scv_random set_global_seed(100); // ランダムのシードを100に設定 scv_smart data_t p( "p" ); p- keep_only( 0, 100 ); // 0~100をランダム生成する p- keep_out( 3, 98); // 3〜98はランダム生成しない for (int i=0; i 10; ++i) { p- next(); printf( "data = %d\n", p.read() ); } 実行結果 data = 100 data = 2 data = 0 data = 1 data = 0 data = 0 data = 99 data = 99 data = 0 data = 100 重み付けランダム生成 例:0〜4の整数を出現率をかえてランダム生成 scv_random set_global_seed(100); scv_bag int dist; dist.add( 0, 50 ); // 50%の割合で0を出現させる dist.add( 1, 30 ); // 30%の割合で1を出現させる dist.add( 2, 10 ); // 10%の割合で2を出現させる dist.add( 3, 8 ); // 8%の割合で3を出現させる dist.add( 4, 2 ); // 2%の割合で4を出現させる scv_smart_ptr int p( "p" ); p- set_mode( dist ); //セット int total = 0; int cnt[5] = {0, 0, 0, 0, 0}; for (int i=0; i 10000; i++) { int p_num; p- next(); // 更新 p_num = p.read(); // ランダム値取得 if (0 = p_num p_num 5) { ++cnt[p_num]; ++total; } } for (int i=0; i 5; i++) { printf( "p=%d, [%4d / %5d]\n", i, cnt[i], total ); } 実行結果 p=0, [5051 / 10000] p=1, [2949 / 10000] p=2, [1038 / 10000] p=3, [ 784 / 10000] p=4, [ 178 / 10000] distで設定されたおおよその出現率でpは出力されていることがわかる。 重み付けランダム生成(レンジ指定) 例:範囲をもった重み付け scv_random set_global_seed(100); scv_bag pair int,int dist; dist.add( pair int,int ( 0, 3), 30 ); // 0〜3の値を30%の割合で出現させる dist.add( pair int,int ( 4,10), 50 ); // 4〜10の値を50%の割合で出現させる dist.add( pair int,int (11,20), 15 ); // 11〜20の値を15%の割合で出現させる dist.add( pair int,int (21,80), 5 ); // 21〜80の値を5%の割合で出現させる scv_smart_ptr int p( "a" ); p- set_mode( dist ); int total = 0; int cnt[5] = {0, 0, 0, 0, 0}; for (int i=0; i 10000; i++) { int p_num; p- next(); p_num = p.read(); if (0 =p_num p_num 4) { ++cnt[0]; ++total; } else if (4 =p_num p_num 11) { ++cnt[1]; ++total; } else if (11 =p_num p_num 21) { ++cnt[2]; ++total; } else if (21 =p_num p_num 81) { ++cnt[3]; ++total; } } printf( "[ 0- 3], [%4d / %5d]\n", cnt[0], total ); printf( "[ 4-10], [%4d / %5d]\n", cnt[1], total ); printf( "[11-20], [%4d / %5d]\n", cnt[2], total ); printf( "[21-80], [%4d / %5d]\n", cnt[3], total ); 実行結果 [ 0- 3], [3047 / 10000] [ 4-10], [4942 / 10000] [11-20], [1500 / 10000] [21-80], [ 511 / 10000] 制限付きランダム生成(scv_constraint_baseの使用) scv_constraint_baseを使うと、制約を1つのクラスにまとめることができるメリットがある。 このクラスは継承することも可能で、制約をより効率的に与えることができるようになる。 例:0〜4または6〜10までの整数値をランダム生成 #include "scv.h" struct data_const public scv_constraint_base { scv_smart_ptr int p; SCV_CONSTRAINT_CTOR(data_const) { SCV_CONSTRAINT( 0 =p() p() 10 p()!=5 ); // ランダム制約 } }; int sc_main( int argc, char* argv[] ) { scv_random set_global_seed(100); data_const data( "data" ); for (int i=0; i 20; i++) { data.next(); // 更新 printf( "data = %d\n", data.p- read() ); // ランダム値取得 } return 0; } 実行結果 data = 7 data = 4 data = 1 data = 0 data = 2 data = 0 data = 6 data = 2 data = 4 data = 7 data = 9 data = 3 data = 9 data = 3 data = 4 data = 4 data = 8 data = 0 data = 6 data = 3 もう少し複雑なランダム生成 構造体を使ったランダム生成 例:ユーザ定義型中の変数をランダム値とする #include "scv.h" // 普通のユーザ定義型を準備 struct mydata_t { sc_uint 16 dat; unsigned char array[3]; }; // ユーザ定義型mydata_tに合わせて定義 SCV_EXTENSIONS( mydata_t ) { public scv_extensions sc_uint 16 dat; scv_extensions unsigned char[3] array; SCV_EXTENSIONS_CTOR( mydata_t ) { SCV_FIELD( dat ); SCV_FIELD( array ); } }; int sc_main( int argc, char* argv[] ) { scv_random set_global_seed(100); mydata_t d; scv_smart_ptr mydata_t p; p- dat.keep_only(0, 10 ); for (int i=0; i 10; i++) { p- next(); // ランダム値更新 d = p- read(); // コピーできる printf( "dat=%d, array=%d, %d, %d\n", (int)d.dat, (int)d.array[0], (int)d.array[1], (int)d.array[2] ); } return 0; } 実行結果 dat=10, array=208, 22, 160 dat=0, array=181, 57, 245 dat=8, array=198, 104, 204 dat=4, array=17, 156, 53 dat=7, array=92, 87, 234 dat=4, array=89, 196, 161 dat=4, array=22, 28, 162 dat=6, array=186, 74, 152 dat=8, array=110, 209, 171 dat=8, array=152, 237, 205 (応用)構造体+条件付きランダム生成 例:ユーザ定義型packet_tを用意→ランダム生成指定 ユーザ定義型を条件付き制約指定 制約を継承して、さらに条件付き制約指定 #include "scv.h" // 通常のユーザ定義型を用意 struct packet_t { sc_uint 32 src_addr; sc_uint 32 dest_addr; sc_uint 16 length; }; //ユーザ定義型packet_tの拡張定義 template class scv_extensions packet_t public scv_extensions_base packet_t { public scv_extensions sc_uint 32 src_addr; scv_extensions sc_uint 32 dest_addr; scv_extensions sc_uint 16 length; SCV_EXTENSIONS_CTOR(packet_t) { SCV_FIELD(src_addr); SCV_FIELD(dest_addr); SCV_FIELD(length); } }; //ユーザ定義型packet_tに対する制約を設定 struct packet_base_constraint public scv_constraint_base { scv_smart_ptr packet_t packet; SCV_CONSTRAINT_CTOR(packet_base_constraint) { // Soft Constraint SCV_SOFT_CONSTRAINT( (packet- length 64) (packet- length 1500) ); // Min Max // Hard Constraint SCV_CONSTRAINT( packet- src_addr() != packet- dest_addr() ); SCV_CONSTRAINT( packet- length() 20 ); } }; // 制約packet_base_constraintを継承して新たな制約packet_constraintをつくる struct packet_constraint public packet_base_constraint { scv_smart_ptr sc_uint 32 dest_min; scv_smart_ptr sc_uint 32 dest_max; SCV_CONSTRAINT_CTOR(packet_constraint) { // use the base constraint SCV_BASE_CONSTRAINT(packet_base_constraint); SCV_CONSTRAINT( (packet- dest_addr() dest_min()) (packet- dest_addr() dest_max()) ); SCV_CONSTRAINT( ((packet- src_addr() (packet- dest_addr() + 0x100000) ) (packet- src_addr() (packet- dest_addr() + 0x200000) )) || ((packet- src_addr() (packet- dest_addr() - 0x10000) )) (packet- src_addr() (packet- dest_addr() - 0xfffff) ) ); SCV_CONSTRAINT( packet- length() == 64 ); } }; int sc_main( int argc, char* argv[] ) { scv_random set_global_seed(100); packet_t pkt; packet_constraint pkt_c( "pkt_c" ); pkt_c.dest_min- disable_randomization(); pkt_c.dest_max- disable_randomization(); *pkt_c.dest_min = 0x100000; *pkt_c.dest_max = 0x800000; for (int i=0; i 10; i++) { pkt_c.next(); pkt = pkt_c.packet- read(); printf( "src_addr = %08x\n", (int)pkt.src_addr ); printf( "dest_addr = %08x\n", (int)pkt.dest_addr ); printf( "length = %d\n", (int)pkt.length ); } return 0; } 実行結果 *** SCV_ERROR CONSTRAINT_ERROR_OVER_CONSTRAINED at time 0 s in process main Constraints for over-constrained object pkt_c will be ignored. src_addr = 008e6617 dest_addr = 00711f52 length = 64 src_addr = 00755da2 dest_addr = 005a4210 length = 64 src_addr = 0054ca51 dest_addr = 006187a8 length = 64 src_addr = 0065a389 dest_addr = 006fd55e length = 64 src_addr = 0046ce02 dest_addr = 004889e1 length = 64 src_addr = 004a19e6 dest_addr = 0059637b length = 64 src_addr = 00268b9a dest_addr = 001069d1 length = 64 src_addr = 0045c242 dest_addr = 004d6c07 length = 64 src_addr = 004e95ef dest_addr = 005d25a4 length = 64 src_addr = 0042bb4e dest_addr = 00313678 length = 64 最初にエラーがでるけど、とりあえず気にしないでおく. おそらく、Soft Constraintに関するエラーだと思われる. その他の使い方 ランダム生成の停止 例:出力を300に固定 scv_smart_ptr int p( "a" ); p- disable_randomization(); // ランダム生成を停止 p- write( 300 ); // pへ値300を書き込む for (int i=0; i 10; i++) { p- next(); // 更新 printf( "data = %d\n", p- read() ); // 値取得 } data = 300 data = 300 data = 300 data = 300 data = 300 data = 300 data = 300 data = 300 data = 300 data = 300 ランダムの停止は、デバッグ時や直接代入したいときに利用できる. 分布の指定 分布の指定は4種類ある。 RAMDAM 指定分布範囲での一様なランダム生成 SCAN とりうる値で小さいものから大きいものへと生成 RANDOM_AVOID_DUPLICATE 生成可能な数値が出尽くすまで同一の値を生成しない DISTRIBUTION scv_bag<>で確率分布を指定 デフォルト設定では、 p- set_mode( RANDOM ); enum scv_extension_rand_if mode_t 順列型ランダム生成(RANDOM_AVOID_DUPLICATE) SystemVerilogのrandcのように順列型の乱数生成のようにできる。 例:0〜9までの順列型のランダム生成 scv_random set_global_seed(100); scv_smart_ptr int p; p- keep_only(0, 9); p- set_mode( scv_extensions_if RANDOM_AVOID_DUPLICATE ); // 分布の指定 for (int i=0; i 2; i++) { for (int j=0; j 10; j++) { p- next(); printf( "%d\n", p- read() ); } printf( "\n" ); } 実行結果 4 1 8 9 7 2 3 6 0 5 8 2 1 5 0 9 4 6 7 3 参照 scv_smart_ptr<T>(実際に使う関数は_scv_extension_rand_N<T>を参照) scv_bag<T>
https://w.atwiki.jp/bambooflow/pages/137.html
Interconnect Component イニシエータとターゲットの間のモデル。 ここでは、ブロッキングI/Fを利用したLTモデルを説明。 b_transoprtメソッドのみの実装を記述。そのほかのメソッドは今回は非サポート。 Interconnect Componentサンプル 構成 TOP Router サンプル b_lt_model_plus_router.tgz 構成 インスタンス関係 sc_main |== top(TOP) |== initiator(Initiator) |== router(Router) |== target[4](Target) 接続関係 initiator == router +== target[0] |== target[1] |== target[2] |== target[3] TOP トップでインスタンスするモジュールは、 イニシエータ1つ(i_socket) ルータ1つ(t_socket, i_socket[4]) ターゲット4つ(t_socket) TOP.h #ifndef __TOP_H_ #define __TOP_H_ #include systemc.h class Initiator; class Target; class Router; SC_MODULE( TOP ) { public TOP( sc_module_name name ); ~TOP(); //private enum { TARGET_MAX = 256 }; Initiator *initiator; Target *target[TARGET_MAX]; Router *router; private const unsigned int targetNum; }; #endif /* __TOP_H_ */ TOP.cpp #include "TOP.h" #include "tlm.h" #include "Initiator.h" #include "Target.h" #include "Router.h" // constructor TOP TOP( sc_module_name name ) sc_module( name ) , targetNum( 4 ) // == setting { sc_assert( 0 targetNum targetNum TARGET_MAX ); // instances initiator = new Initiator( "initiator" ); router = new Router( "router", targetNum ); for (unsigned int i=0; i targetNum; i++) { char t_name[20]; sprintf( t_name, "target_%d", i ); target[i] = new Target( t_name ); } // binding initiator- i_socket.bind( router- t_socket ); for (unsigned int i=0; i targetNum; i++) router- i_socket[i]- bind( target[i]- t_socket ); } // destructor TOP ~TOP() { delete initiator; delete router; for (unsigned int i=0; i targetNum; i++) { delete target[i]; } } Router ルータはイニシエータからのリクエストを接続されているターゲットに渡す中間モジュール。 複数ターゲットが接続されているので、上位ビットをみてそれぞれのターゲットにリクエストを振り分ける。 Router.h #ifndef __ROUTER_H_ #define __ROUTER_H_ #include systemc.h #include "tlm.h" SC_MODULE( Router ) , public tlm tlm_fw_transport_if , public tlm tlm_bw_transport_if { enum { TARGET_MAX = 256 }; tlm tlm_initiator_socket 32 *i_socket[TARGET_MAX]; tlm tlm_target_socket 32 t_socket; SC_HAS_PROCESS( Router ); Router( sc_module_name name, const unsigned int target_um=4 ); ~Router(); protected // I/F functions // FW virtual void b_transport( tlm tlm_generic_payload trans, sc_time time ) ; virtual tlm tlm_sync_enum nb_transport_fw( tlm tlm_generic_payload trans, tlm tlm_phase phase, sc_time time ); virtual unsigned int transport_dbg( tlm tlm_generic_payload trans ); virtual bool get_direct_mem_ptr( tlm tlm_generic_payload trans, tlm tlm_dmi dmi); // BW virtual tlm tlm_sync_enum nb_transport_bw( tlm tlm_generic_payload trans, tlm tlm_phase phase, sc_time time ); virtual void invalidate_direct_mem_ptr( sc_dt uint64 a, sc_dt uint64 b); // functions unsigned int decode_address( unsigned int address, unsigned int masked_address ); sc_dt uint64 compose_address( unsigned int target_nr, sc_dt uint64 address); private const unsigned int targetNum; }; #endif /* __ROUTER_H_ */ Router.cpp #include "Router.h" // constructor Router Router( sc_module_name name, const unsigned int target_num ) sc_module( name ) //, i_socket( "i_socket" ) , t_socket( "t_socket" ) , targetNum( target_num ) { sc_assert( (0 targetNum) (targetNum TARGET_MAX) ); for (unsigned int i=0; i targetNum; i++) { char socket_name[20]; sprintf( socket_name, "i_socket_%d", i ); i_socket[i] = new tlm tlm_initiator_socket 32 ( socket_name ); i_socket[i]- bind( *this ); // I/Fとバインド } t_socket.bind( *this ); // I/Fとバインド } Router ~Router() { for (unsigned int i=0; i targetNum; i++) { delete i_socket[i]; } } unsigned int Router decode_address( unsigned int address, unsigned int masked_address ) { unsigned int target_nr = (address 16) 0xff; // target_nr is 0~255 masked_address = address 0xffff; return target_nr; } sc_dt uint64 Router compose_address( unsigned int target_nr, sc_dt uint64 address) { return (target_nr 16) | (address 0xffff); } // FW void Router b_transport( tlm tlm_generic_payload trans, sc_time time ) { trans.set_response_status( tlm TLM_ADDRESS_ERROR_RESPONSE ); unsigned int address = static_cast unsigned int (trans.get_address()); unsigned int masked_address; // mask 0x0000ffff unsigned int target_nr; target_nr = decode_address( address, masked_address ); if (target_nr targetNum) { trans.set_address( masked_address ); (*i_socket[target_nr])- b_transport( trans, time ); } else { cout name() " ERROR, can not access Target No." target_nr endl; trans.set_response_status( tlm TLM_ADDRESS_ERROR_RESPONSE ); } } // FW tlm tlm_sync_enum Router nb_transport_fw( tlm tlm_generic_payload trans, tlm tlm_phase phase, sc_time time ) { cout "nb_transport_fw is not supoorted." endl; trans.set_response_status( tlm TLM_GENERIC_ERROR_RESPONSE ); return tlm TLM_COMPLETED; } // FW unsigned int Router transport_dbg( tlm tlm_generic_payload trans ) { //sc_dt uint64 masked_address; //unsigned int target_nr = decode_address( trans.get_address(), masked_address ); //return (*i_socket[target_nr])- transport_dbg( trans ); return 0; // Debug not supported } bool Router get_direct_mem_ptr( tlm tlm_generic_payload trans, tlm tlm_dmi dmi) { //uint64 masked_address; //unsigned int target_nr = decode_address( trans.get_address(), masked_address ); //bool status = (*i_socket[target_nr])- get_direct_mem_ptr( masked_address, dmi ); //dmi.set_start_address( compose_address( target_nr, dmi.get_start_address() ) ); //dmi.set_end_address( compose_address( target_nr, dmi.get_end_address() ) ); //return status; return false; // DMI not supported } // BW tlm tlm_sync_enum Router nb_transport_bw( tlm tlm_generic_payload trans, tlm tlm_phase phase, sc_time time ) { // not support trans.set_response_status( tlm TLM_GENERIC_ERROR_RESPONSE ); return tlm TLM_COMPLETED; } // BW void Router invalidate_direct_mem_ptr( sc_dt uint64 a, sc_dt uint64 b) { // DMI unused // t_socket- invalidate_direct_mem_ptr( 0, (sc_dt uint64)-1 ); }
https://w.atwiki.jp/kanikanise/pages/53.html
TRN 大人の事件簿 第一章 少々お待ちいただけますか そう・・・ そんなことしなくていいから 野球か何か
https://w.atwiki.jp/procearphones/pages/15.html
TRN Vシリーズ v10 v20 V60 v80